package com.dayaokeji.rhythmschoolstudent.client.common.base;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Application;
import android.app.Notification;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.os.Process;
import android.os.StrictMode;
import android.support.multidex.MultiDex;

import com.beetle.bauhinia.api.IMHttpAPI;
import com.bilibili.boxing.BoxingCrop;
import com.bilibili.boxing.BoxingMediaLoader;
import com.dayaokeji.rhythmschoolstudent.BuildConfig;
import com.dayaokeji.rhythmschoolstudent.R;
import com.dayaokeji.rhythmschoolstudent.boxing.impl.BoxingCropImpl;
import com.dayaokeji.rhythmschoolstudent.boxing.impl.BoxingGlideLoader;
import com.dayaokeji.rhythmschoolstudent.client.common.AppErrorActivity;
import com.dayaokeji.rhythmschoolstudent.client.main.MainActivity;
import com.dayaokeji.rhythmschoolstudent.client.main.SplashActivity;
import com.dayaokeji.rhythmschoolstudent.client.mine.account.StudentIdLoginActivity;
import com.dayaokeji.rhythmschoolstudent.client.mine.account.bean.RemoteHostPicker;
import com.dayaokeji.rhythmschoolstudent.databases.LiteOrmUtils;
import com.dayaokeji.rhythmschoolstudent.event.AppStateEvent;
import com.dayaokeji.rhythmschoolstudent.utils.ACache;
import com.dayaokeji.rhythmschoolstudent.utils.AndroidUtils;
import com.dayaokeji.rhythmschoolstudent.utils.DensityUtil;
import com.dayaokeji.rhythmschoolstudent.utils.RemoteHostUtil;
import com.dayaokeji.rhythmschoolstudent.utils.UserUtils;
import com.dayaokeji.server_api.AccessTokenProvider;
import com.dayaokeji.server_api.ApiUtils;
import com.facebook.stetho.Stetho;
import com.litesuits.orm.LiteOrm;
import com.orhanobut.logger.AndroidLogAdapter;
import com.orhanobut.logger.DiskLogAdapter;
import com.orhanobut.logger.Logger;
import com.tencent.bugly.Bugly;
import com.tencent.bugly.beta.Beta;
import com.tencent.bugly.crashreport.CrashReport;

import org.greenrobot.eventbus.EventBus;

import cat.ereza.customactivityoncrash.config.CaocConfig;
import cn.jpush.android.api.BasicPushNotificationBuilder;
import cn.jpush.android.api.JPushInterface;
import cn.jpush.sms.SMSSDK;
import me.jessyan.retrofiturlmanager.RetrofitUrlManager;


/**
 * Created by Gorden on 2017/9/23.
 */

public class App extends Application {

    private static Application app;
    private boolean isBackground = true;
    private int activityCount;

    public App() {
        app = this;
    }

    public static Context getAppContext() {
        return app.getApplicationContext();
    }

    public static App getInstance() {
        return ((App) app);
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(base);
    }

    @Override
    public void onCreate() {
        super.onCreate();

        boolean isMainProcess = getPackageName().equals(AndroidUtils.getProcessName(this, Process.myPid()));
        if (isMainProcess) {
            loggerConfig();
            buglyConfig();
            initJPushSms();
            initJPush();
            initServerApi();
            initBoxing();
            listenForForeground();
            listenForScreenTurningOff();
            crashHandle();
            setupStetho();
            setUrlManager();
            setIm();
            setBaseUrl();
            DensityUtil.setDensity(this);
            version7();
        }
    }

    @SuppressLint("NewApi")
    private void version7()  {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
            StrictMode.setVmPolicy(builder.build());
            builder.detectFileUriExposure();
        }
    }

    private void setUrlManager() {
        RetrofitUrlManager.getInstance().setDebug(true);
    }

    private void setupStetho() {
        if (BuildConfig.DEBUG) {
            Stetho.initializeWithDefaults(getAppContext());
        }
    }

    private void setIm() {
        IMHttpAPI.setHeaderToken(UserUtils.getAccessToken());
    }

    // set base url
    private void setBaseUrl() {
        RemoteHostUtil.asyncRemoteHost();
        RemoteHostPicker currentRemoteHost = RemoteHostUtil.getCurrentRemoteHost();
        if (currentRemoteHost != null) {
            Logger.d("app set base url --- "+currentRemoteHost.getHost());
        }
    }

    /**
     * 初始化日志输出
     */
    private void loggerConfig() {
        Logger.addLogAdapter(new AndroidLogAdapter(){
            @Override
            public boolean isLoggable(int priority, String tag) {
                return BuildConfig.DEBUG;
            }

            @Override
            public void log(int priority, String tag, String message) {
                super.log(priority, "RhythmSchoolStudent", message);
            }
        });
        Logger.addLogAdapter(new DiskLogAdapter());
    }

    /**
     * 初始化bugly ， 线上收集错误日志
     */
    private void buglyConfig() {
        Beta.autoInit = true;
        Beta.autoCheckUpgrade = true;
        Beta.largeIconId = R.mipmap.ic_launcher;
        Beta.smallIconId = R.mipmap.ic_launcher;
        Beta.showInterruptedStrategy = true;
        Beta.canShowUpgradeActs.add(MainActivity.class);
        Beta.canShowUpgradeActs.add(StudentIdLoginActivity.class);
        Bugly.init(getAppContext(),"bdb322f631",BuildConfig.DEBUG);
        CrashReport.setIsDevelopmentDevice(getAppContext(),BuildConfig.DEBUG);
    }

    /**
     * 初始化retrofit
     */
    private void initServerApi() {
        ApiUtils.init(new AccessTokenProvider() {
            @Override
            public String getToken() {
                return UserUtils.getAccessToken();
            }
        }, new com.dayaokeji.server_api.Logger() {
            @Override
            public void log(Type type,String log) {
                switch (type) {
                    case RAW:
                        if (!log.contains("<body>") || !log.contains("<html>")) {
                            Logger.d(log);
                        }
                        break;
                    case JSON:
                        try{
                            Logger.json(log);
                        }catch (Exception e) {
                            Logger.i(log);
                        }
                        break;
                }
            }
        },!BuildConfig.DEBUG);
    }


    /**
     * 极光短信
     */
    private void initJPushSms() {
        SMSSDK.getInstance().initSdk(this);
        SMSSDK.getInstance().setDebugMode(BuildConfig.DEBUG);
    }

    /**
     * 初始化图片选择器
     */
    private void initBoxing() {
        BoxingMediaLoader.getInstance().init(new BoxingGlideLoader());
        BoxingCrop.getInstance().init(new BoxingCropImpl());
    }

    /**
     * 初始化极光推送
     */
    public void initJPush() {
        JPushInterface.setDebugMode(BuildConfig.DEBUG); 	// 设置开启日志,发布时请关闭日志
        JPushInterface.init(this);  // 初始化 JPush
        JPushInterface.setChannel(this, "通知");
        setJPushNotificationStyle();
    }

    /**
     * 设置Notification Style
     */
    private void setJPushNotificationStyle() {
        BasicPushNotificationBuilder builder = new BasicPushNotificationBuilder(this);
        builder.statusBarDrawable = R.mipmap.ic_launcher;
        builder.notificationDefaults = Notification.DEFAULT_SOUND;
        builder.notificationFlags = Notification.FLAG_AUTO_CANCEL;
        JPushInterface.setPushNotificationBuilder(1,builder);

    }

    /**
     * LiteOrm数据库对象
     * @return
     */
    public LiteOrm getLiteOrm() {
        return LiteOrmUtils.getLiteOrm(getAppContext());
    }




    /**
     * data cache
     * @return
     */
    public ACache getAcache() {
        return ACache.get(getAppContext());
    }

    /**
     * App crash handle
     */
    private void crashHandle() {
        CaocConfig.Builder.create()
                .enabled(true)
                .showRestartButton(true)
                .restartActivity(SplashActivity.class)
                .errorActivity(AppErrorActivity.class)
                .errorDrawable(R.mipmap.ic_launcher)
                .apply();
    }

    private void listenForForeground(){
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {

            }

            @Override
            public void onActivityStarted(Activity activity) {
                activityCount++;
            }

            @Override
            public void onActivityResumed(Activity activity) {
                if (isBackground) {
                    isBackground = false;
                    notifyForeground();
                }
            }

            @Override
            public void onActivityPaused(Activity activity) {

            }

            @Override
            public void onActivityStopped(Activity activity) {
                activityCount--;
                if (activityCount == 0) {
                    if (!AndroidUtils.runningTopActivity()) {
                        isBackground = true;
                        notifyBackground();
                    }else{
                        isBackground = false;
                    }
                }
            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

            }

            @Override
            public void onActivityDestroyed(Activity activity) {
            }
        });
    }

    private void listenForScreenTurningOff(){
        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
        registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (!isBackground) {
                    EventBus.getDefault().post(new AppStateEvent(true,Constant.APP_STATE_TURNING_OFF));
                }
                Logger.d("ForScreenTurningOff()");
            }
        }, intentFilter);
    }

    private void notifyBackground() {
        Logger.d("notifyBackground()");
        EventBus.getDefault().post(new AppStateEvent(false,Constant.APP_STATE_EXIT_CODE));
    }

    private void notifyForeground() {
        Logger.d("notifyForeground()");
        EventBus.getDefault().post(new AppStateEvent(true,Constant.APP_STATE_FOREGROUND_CODE));
    }
}
